/*
 * ScalaCheck
 * Copyright (c) 2007-2021 Rickard Nilsson. All rights reserved.
 * http://www.scalacheck.org
 *
 * This software is released under the terms of the Revised BSD License.
 * There is NO WARRANTY. See the file LICENSE for the full text.
 */

package org.scalacheck

import org.scalacheck.Prop.AnyOperators
import org.scalacheck.Prop.forAll

import java.util.HashMap
import scala.collection.JavaConverters.*
import scala.collection.immutable.IntMap

object IntMapSpec extends org.scalacheck.Properties("IntMap") {

  /** Compare a HashMap and an IntMap for equality */
  private def eqMaps(hm: HashMap[Int, Any], im: IntMap[Any]) = {
    im.keys.forall(hm.containsKey) &&
    hm.keySet.containsAll(im.keys.asJavaCollection) &&
    im.keys.forall(k => im(k) == hm.asScala(k))
  }

  /** Create an IntMap and a HashMap with the same contents */
  private def createMaps(l: List[Int]) = {
    val mappings = for (n <- l) yield (n, new Object)
    val im = IntMap(mappings*)
    val hm = new HashMap[Int, Any]
    for ((n, x) <- mappings) hm.put(n, x)
    (hm, im)
  }

  property("size") = forAll { (l: List[Int]) =>
    val (refMap, intMap) = createMaps(l)
    intMap.size ?= refMap.size
  }
  property("isEmpty") = forAll { (l: List[Int]) =>
    val (refMap, intMap) = createMaps(l)
    intMap.isEmpty ?= refMap.isEmpty
  }
  property("add") = forAll { (l: List[Int], k: Int, v: String) =>
    val (refMap, intMap) = createMaps(l)
    refMap.put(k, v)
    eqMaps(refMap, intMap + (k -> v))
  }
  property("remove") = forAll { (l: List[Int], k: Int) =>
    val (refMap, intMap) = createMaps(l)
    refMap.remove(k)
    eqMaps(refMap, intMap - k)
  }
}
